jacekp 2003/07/01 13:03:43
Added: flood/docs README flood/docs/docbook Makefile flood.xml Log: Flood manual (at least...) Revision Changes Path 1.1 httpd-test/flood/docs/README Index: README =================================================================== * How to build flood documentation 1. Get DocBook DTD and XSL For DTD go to: http://www.oasis-open.org/docbook/xml/ ...and download recent DocBook DTD (v4.2 at the time of writting). For XSL part go to: http://sourceforge.net/projects/docbook/ and download recent docbook-xsl (1.61.3 at the time of writting). Unpack tarballs and move to suitable directory. Most Linux distros use /usr/share/sgml/docbook for that, but it can be anywhere. To make things simple, please declare enviroment variable DOCBOOK, that points to XSL root directory. 2. Get recent toolchain You'll need decent XSLT procesor, since DocBook stylesheets are complex. Just pick one: Xalan -- http://xml.apache.org/xalan-j/ Saxon -- http://saxon.sf.net/ xsltproc -- http://www.xmlsoft.org/ sablotron -- http://www.gingerall.org/charlie/ga/xml/p_sab.xml XT -- http://www.jclark.com/xml/xt.html Author of this document uses xsltproc most of the time, and because of that Makefile is tailored at this software. If you happen to like other XSLT engine -- please post a patch. 3. Change DTD location Source XML file (docbook/flood.xml) needs to be tweaked a bit. You have to change DTD location there (which reflects my development enviroment) to match your system. Just edit line number 2 with your favourite editor. 3. Translate files Just use your XSLT engine. Feed it: 1. DocBook source -- docbook/flood.xml 2. DocBook XSL -- $DOCBOOK/xhtml/chunked.xsl Of course, you can substitute another format instead of xhtml. Look at XSL root directory to see what formats are available. 4. Read docs, find bugs, post patches You might look for FIXME strings in XML source if you need an issue to work on. When adding new configration element, look for template near end of XML source. You might find following resources handy when preparing patches: http://www.docbook.org/tdg/ http://www.dpawson.co.uk/docbook/ http://docbook.org/wiki/ 1.1 httpd-test/flood/docs/docbook/Makefile Index: Makefile =================================================================== # xsltproc location xsltproc = /usr/bin/xsltproc # docbook stylesheets location docbook = /usr/share/sgml/docbook/xsl-stylesheets-1.57.0 xhtml: flood.xml ${xsltproc} -o ../manual/ ${docbook}/xhtml/chunk.xsl flood.xml clean: rm -f ../manual/*.html 1.1 httpd-test/flood/docs/docbook/flood.xml Index: flood.xml =================================================================== <?xml version="1.0" standalone="no"?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "file:///usr/share/sgml/docbook/xml-dtd-4.1.2/docbookx.dtd"> <book> <bookinfo> <title>Flood manual</title> <author> <firstname>Jacek</firstname> <surname>Prucia</surname> </author> <copyright> <year>2003</year> <holder>Apache Software Foundation</holder> </copyright> </bookinfo> <preface> <title>Foreword</title> This manual describes Flood. A software developed by Apache Software Foundation. </preface> <!-- Introduction to Flood --> <chapter> <title>Introduction to Flood</title> <para> Flood is a profile-driven HTTP load tester. It is a software that is capable of generating large amount of web traffic, so you can measure performance of your web application. Flood can also postprocess web server responses, so you also can check your web application for correct behaviour. </para> <para> Being profile-driven means, that nearly all actions related to creating and performing a request, are controlled by a set of rules. Those rules together create a profile. By using different profiles and the same set of URLs, you might get quite different results. Moreover, particular profiles are usefull in conjunction with different types of tests. As far as web applications are concerned, we can distinguish three types of tests. These are: </para> <orderedlist> <listitem> Performance test. This test measures response time of web server. Desired result is usually a Requests Per Second for given resource or average for all pages hit. </listitem> <listitem> Regression test. This test doublechecks behaviour of web application, by simulating several user actions (so called URL paths). It is supposed to give answer to question: Is my web application working correctly? </listitem> <listitem> Web capacity test. This test performs numerous parallel requests, simulating really heavy ussage of web application. It is supposed to answer question: does my web application and web server handle given load? </listitem> </orderedlist> <para> With a little bit of tweaking flood can be useful, regardless of which type of test you are going to perform. </para> <para> Flood aims to be modular and extensible. It is fairly easy to write flood extension providing new functionality. Hence flood can be easily extended to suit just about everybody needs. Right now it can be used in most enviroments without the need for writting external modules. Current flood feature list follows: </para> <itemizedlist> <listitem>HTTP/1.0 and HTTP/1.1 support</listitem> <listitem>HTTPS support</listitem> <listitem>GET/POST/HEAD support</listitem> <listitem>reponse postprocessing</listitem> <listitem>basic support for AUTH and Cookies</listitem> <listitem>different report modules (different presentation of results) </listitem> </itemizedlist> <para> Flood has a homepage available: <ulink url="http://httpd.apache.org/test/flood/"> http://httpd.apache.org/test/flood</ulink>. Be sure to check it often for news and releases. If you have a burning question, or would like to report a problem (patches welcome), then please subscribe to flood developemnt mailing list: [EMAIL PROTECTED], by sending an empty e-mail to adress: <email>[EMAIL PROTECTED]</email> and following instructions in response. </para> </chapter> <!-- Getting Flood --> <chapter> <title>Getting Flood</title> <para>There are three ways in which you can get flood software.</para> <section> <title>Source Tarball</title> <para> This is the official way of obtaining flood source. Current flood release can be found here: </para> <ulink url="http://www.apache.org/dist/httpd/flood/"> http://www.apache.org/dist/httpd/flood/ </ulink> <para> Alternativelly, you can pick up a nearby mirror using this list: </para> <ulink url="http://www.apache.org/dyn/closer.cgi"> http://www.apache.org/dyn/closer.cgi </ulink> <para> Every official release schould be acompanied by everything you need to build and use flood. That includes all external libraries (except for SSL which is due to cryptography export restrictions) and documentation. </para> </section> <section> <title>CVS Repository</title> <para> You can get flood source code directly from CVS repository. All you have to do (besides getting CVS software itself) is to issue following commands: </para> <screen> $ cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic login $ cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic co httpd-test/flood </screen> <para> Note, that with CVS repository you're basically on your own with meeting build dependencies. So you'll have to get apr libraries as well: </para> <screen> $ cd httpd-test/flood $ cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic co apr $ cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic co apr-util </screen> <para> Please note that source code from CVS might not compile under certain circumstances, so don't expect it to be as stable as official releases. On the other hand, you schould try CVS repository before reporting a problem. There is a huge chance, that your bug is already fixed. </para> </section> <section> <title>Flood binaries</title> <para> Additionally, when flood developers will have some free time, binary versions of flood official releases may show up on main flood site: </para> <ulink url="http://www.apache.org/dist/httpd/flood/"> http://www.apache.org/dist/httpd/flood/ </ulink> <para> If you find binary release that matches your platform, please consult file <filename>README.binary</filename> located in the root directory of binary packages, for information how flood was compiled for your platform, and what features are available. </para> </section> </chapter> <!-- Compiling and installing --> <chapter> <title>Compiling and installing</title> <para> There are two scenarios for compillation and installation of flood. </para> <section> <title>Unix</title> <para> Flood is build around apr and apr-util, so most Unix platforms will work out of the box. Currently flood is developed on Linux and Solaris, but FreeBSD is also known to work. </para> <para> Before compilation we have to configure source tree for your particular platform and personal requirements. You can do that using <command>configure</command> script which is located in the root directory of the flood source distribution. If you have obtained flood sources from CVS, then you'll need to run <command>buildconf</command> first (note that this requires recent versions of <application>autoconf</application> and <application>libtool</application> installed). <command>configure</command> script recognizes following options: </para> <itemizedlist> <listitem> <option>--prefix=PREFIX</option> <para> Specifies target directory, which will contain all installed files. Defaults to <filename class="directory">/usr/local/flood</filename>. </para> </listitem> <listitem> <option>--enable-ssl</option> <para> This switch will cause flood to be built with SSL support, which is disabled by default because of cryptography export restrictions. </para> </listitem> <listitem> <option>--with-openssl=PATH</option> <para>Path to directory containing OpenSSL installation.</para> </listitem> <listitem> <option>--with-capath=PREFIX</option> <para> Path to a directory with c_rehash'd CA files used by OpenSSL. Defaults to <filename class="directory">/certs</filename>. </para> </listitem> <listitem> <option>--with-apr=DIR|FILE</option> <para> Prefix for installed APR, path to APR build tree, or the full path to <command>apr-config</command>. </para> </listitem> <listitem> <option>--with-apr-util=DIR</option> <para>Prefix for installed APU, or path to APU build tree.</para> </listitem> </itemizedlist> <para> A typical example of relevant command line: </para> <screen> ./configure --enable-ssl </screen> <para> When flood source tree is configured you can start compilation by typing make at command prompt: </para> <screen> make </screen> <para> When compilation finishes, you'll have to perform last step -- installation. This is done by typing make install at command prompt: </para> <screen> make install </screen> <para> Please note, that you will need write permissions for install directory. This may require you to obtain root privileges. </para> <para> If you have followed those instructions carefully, but still couldn't get flood sources to compile, then please send e-mail to <email>[EMAIL PROTECTED]</email> mailing list, with description of your problem. </para> </section> <section> <title>Windows</title> <para> This section needs to be written. If there are no Win32 GURU to help, I'll try to play around <filename>flood.dsp</filename> a bit -- jacekp. </para> </section> </chapter> <!-- Running Flood --> <chapter> <title>Running Flood</title> <para> Flood is a command line software. You can run it from Unix shell, MS-DOS prompt or simmilar facility of your operating system. Flood accepts only one argument, and that is a path to configuration file. Example: </para> <screen> $ flood /home/jacekp/tests/simple-test.xml </screen> <para> If no argument is given, then flood uses standard input stream (<filename>stdin</filename>), so you can use flood in pipe processing: </para> <screen> $ get_urls.py /var/log/apache/access.log | flood </screen> <para> Flood outputs results to standard output stream (<filename>stdout</filename>) and errors (if any) to standard error stream (<filename>stderr</filename>). You can save result to file, or pipe it to flood processing script, like this: </para> <screen> $ flood /home/jacekp/tests/simple-test.xml > /home/jacekp/tests/simple-test.out $ flood /home/jacekp/tests/simple-test.xml | analize-relative </screen> <para> If flood is used in shell scripts, then you can test $? variable for flood return code. If the code is 0, then flood has performed a successful test. Other value (usually greater than 0) means, that there was error during test. </para> <para> There's ongoing development of GUI application for flood. When usable, such application will make working with flood much easier. </para> </chapter> <!-- Flood Configuration File --> <chapter> <title>Flood Configuration File</title> <para>This sections discusses flood configuration file.</para> <section> <title>About File format</title> <para> Flood XML parsing is built around apr-util XML capabilities, which in turn are based on tweaked version of James Clark's marvelous expat library. Because of that flood understands XML v1.0, so you schould start your configuration file with following processing instruction (PI for short): </para> <screen> <?xml version="1.0"?> </screen> <para> It is not required by flood, but it's good practice and may be useful if you decide to use other XML tools for additional processing. Please note, that expat support for different encodings is rather limited. In particular it understands only UTF-8 and ISO-8859-1 encodings, so processing of your configuration may fail if you specify different encoding in your configuration file, like this: </para> <screen> <?xml version="1.0" encoding="iso-8859-2"?> </screen> <para> Please note, that you can get around that limitation, by converting you national characters to UTF-8. Flood itself only checks XML file for well-formdess, which means checking if it is formed after basic XML rules. If you want to do full validation of flood configuration file, you may want to include following line right next to XML processing instruction: </para> <screen> <!DOCTYPE configuration SYSTEM "file://path/to/flood.dtd"> </screen> <para> Of course, you have to substitute <filename>/path/to/flood.dtd</filename> with a real path to flood DTD. With this declaration you can use software with validating XML parser (like ASF's Xalan) and validate your configuration before actually processing it with flood. That way you can ensure, that flood.xml file is valid and obeys flood configuration rules. </para> <para> Please note that all configure elements in flood aren't using their own dedicated XML namespace, so if you (for some reason) intend to mix flood configuration file with other XML, you may experience tag name collision. </para> </section> <section> <title>XML Survival Guide</title> <para> Preparing flood configuration file can be a little troublesome. At the time of writting this manual there are no external tools, that could aid in this process (although there are plans to develop those -- see next chapter). So you have to pick up editor that has some sort of XML support. For various Unix systems <application>vi</application> and <application>emacs</application> seems to be reasonable choices. You'll get colored syntax, possibly run-time (that is -- as you type) DTD checking and maybe other switches to help you work with XML files. </para> <para> There are characters that are used by XML markup itself, and you need a bit of magic when you want to use them as plain text. Everytime you need such a character, you'll have to reference it by an XML entity. XML entities start with ampersand (character '&') and end with semicolon (character ';'). Text between those character must refer to valid XML entity. Below is a table that lists all 'reserved' XML characters and their coresponding XML entities. </para> <!-- <table frame="all"> --> <informaltable frame="all"> <!-- <title>Predefined character entities</title> --> <tgroup cols="3" align="center"> <thead> <row> <entry>character name</entry> <entry>character glyph</entry> <entry>entity</entry> </row> </thead> <tbody> <row> <entry>ampersand</entry> <entry>&</entry> <entry>&amp;</entry> </row> <row> <entry>less than</entry> <entry><</entry> <entry>&lt;</entry> </row> <row> <entry>greater than</entry> <entry>></entry> <entry>&gt;</entry> </row> <row> <entry>apostrophe</entry> <entry>'</entry> <entry>&apos;</entry> </row> <row> <entry>quotation mark</entry> <entry>"</entry> <entry>&quot;</entry> </row> </tbody> </tgroup> <!-- </table> --> </informaltable> <para> If you intend to use international characters in your flood configuration file, and you don't have Unicode enabled editor, you'll have to encode those characters. XML has special entity for including just about any UTF-8 character. Basically it is &#XXX; for decimal and &#xXXX for hex where XXX is a Unicode character position. For example, polish letter "small letter a with ogonek" can be referenced as &#261; (decimal) or &#x105; (hex) while german umlaut (latin small letter u with diaeresis) schould be entered as &#252; (decimal) or &#xFC (hex). If you intend to use a lot of international characters, you'd better get Unicode enabled text editor, since number of XML entities will make your flood configuration file ugly (not to mention typing hassle). <!-- maybe a link to: http://skew.org/xml/tutorial/ --> </para> </section> <section> <title>Mass URLs retrieval</title> <para> Basic configuration examples are pretty easy to write, mostly because the contain as little as 5, maybe 10 URLs. When you intend to do serious tests of a large site or web application, you may be unwilling to hand-type, say 600 URLs by hand. Flood is going to help you with several applications under development: </para> <orderedlist> <listitem>mozilla application</listitem> <listitem>small proxy</listitem> <listitem>apache module</listitem> <listitem>log file analizer</listitem> </orderedlist> </section> </chapter> <chapter> <title>Flood Configuration Elements</title> <para> This section describes flood configuration elements an their meaning. All elements are presented here as a flat list, so please start browsing with root element (which is: <envar><flood></envar>) to get idea what elements are available. </para> <refentry id="flood"> <refmeta> <refentrytitle>flood</refentrytitle> </refmeta> <refnamediv> <refname>flood</refname> <refpurpose>root element</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><flood> ... </flood></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <para>none (this is the root element).</para> </refsection> <refsection> <title>children elements</title> <synopsis><link linkend="urllist"><urllist></link>+ <link linkend="profile"><profile></link>+ <link linkend="farmer"><farmer></link>+ <link linkend="farm"><farm></link>+ [ <link linkend="seed"><seed></link> ]</synopsis> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>ignored.</para> </refsection> <refsection> <title>description</title> <para> This is the top level element for flood configuration file. It schould contain at least: one urllist, one profile, one farmer and one farm. </para> </refsection> <refsection> <title>examples</title> <para>bellow is a smallest usable flood configuration file</para> <screen> <?xml version="1.0"?> <flood> <urllist> <name>single url</name> <url>http://www.example.com/</url> </urllist> <profile> <name>simple profile</name> <useurllist>single url</useurllist> <profiletype>round_robin</profiletype> <report>relative_times</report> <verify_resp>verify_200</verify_resp> </profile> <farmer> <name>john</name> <useprofile>simple profile</useprofile> </farmer> <farm> <!-- please note that right now faram *MUST* be called "Bingo" --> <name>Bingo</name> <usefarmer>john</usefarmer> </farm> </flood> </screen> </refsection> </refentry> <refentry id="urllist"> <refmeta> <refentrytitle>urllist</refentrytitle> </refmeta> <refnamediv> <refname>urllist</refname> <refpurpose>groups several url adressess</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><urllist> ... </urllist></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="flood"><flood></link></synopsis> </refsection> <refsection> <title>children elements</title> <synopsis><link linkend="name"><name></link> [ <link linkend="description"><description></link> ] <link linkend="baseurl"><baseurl></link> <link linkend="url"><url></link>* <link linkend="sequence"><sequence></link>*</synopsis> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>ignored.</para> </refsection> <refsection> <title>description</title> <para> This element is a container for <url> elements, which are basic data unit of flood. Every flood configuration file must have at least one urllist element. Every urllist must be asociated with name (using <name> children element) and optionally with description. </para> <para> When combined with proper profile type, this element allows a creation of url paths. That means a sequence of url addresses, that simulate a real human behaviour, such as: logon to service, retrieve random (or specified) article, logoff. </para> </refsection> <refsection> <title>examples</title> <screen> <urllist> <name>single url</name> <url>http://www.example.com/</url> </urllist> </screen> </refsection> </refentry> <refentry id="name"> <refmeta> <refentrytitle>name</refentrytitle> </refmeta> <refnamediv> <refname>name</refname> <refpurpose>names object referenced by parent element</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><name>STRING</name></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis>{ <link linkend="urllist"><urllist></link> | <link linkend="profile"><profile></link> | <link linkend="farmer"><farmer></link> | <link linkend="farm"><farm></link> }</synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>specifies name of object referenced by parent element.</para> </refsection> <refsection> <title>description</title> <para> This element sets name of object identified by parent element. Most of the time, this element is mandatory, as it allows to reference objects by their names. </para> </refsection> <refsection> <title>examples</title> <screen> <urllist> <name>single url</name> <!-- ... --> </urllist> </screen> </refsection> </refentry> <refentry id="description"> <refmeta> <refentrytitle>description</refentrytitle> </refmeta> <refnamediv> <refname>description</refname> <refpurpose>description of object identified by parent element</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><description>STRING</description></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis>{ <link linkend="urllist"><urllist></link> | <link linkend="profile"><profile></link> | <link linkend="farmer"><farmer></link> | <link linkend="farm"><farm></link> }</synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>description of object identified by parent element</para> </refsection> <refsection> <title>description</title> <para> This element allows asociation of description with object identified by parent element. It is usually optional and is useful only in conjunction with GUI frontend. It isn't used by flood at all. </para> </refsection> <refsection> <title>examples</title> <screen> <urllist> <name>my urllist</name> <description>a bunch of random pages</desccription> <!-- ... --> </urllist> </screen> </refsection> </refentry> <refentry id="baseurl"> <refmeta> <refentrytitle>baseurl</refentrytitle> </refmeta> <refnamediv> <refname>baseurl</refname> <refpurpose>base URL for all url elements</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><baseurl>STRING</baseurl></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="urllist"><urllist></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>base url.</para> </refsection> <refsection> <title>description</title> <para> This element sets base URL for all url elements in current urllist. Every URL is created by concatenating base url and url itself. This allows to abstract urllist and move it around easy. </para> </refsection> <refsection> <title>examples</title> <screen> <urllist> <!-- ... --> <baseurl>http://www.example.com</baseurl> <url>/foo.html</url> <url>/bar.html</url> </urllist> </screen> </refsection> </refentry> <refentry id="url"> <refmeta> <refentrytitle>url</refentrytitle> </refmeta> <refnamediv> <refname>url</refname> <refpurpose>specifies URL address for retrieval</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <!-- FIXME: this looks ugly... maybe some sort of tabbing? --> <synopsis><url [ method="{ GET | POST | HEAD }" ] [ payload="STRING" ] [ payloadparam="STRING" ] [ payloadparamcount="INTEGER" ] [ payloadtemplate="STRING" ] [ responsename="STRING" ] [ responsetemplate="STRING" ] [ requesttemplate="STRING" ] [ requestparamcount="INTEGER" ] [ predelay="INTEGER" ] [ predelayprecision="INTEGER" ] [ postdelay="INTEGER" ] [ postdelayprecision="INTEGER" ] [ user="STRING" ] [ password="STRING" ]> [ STRING</url> ]</synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="urllist"><urllist></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <informaltable frame="all"> <tgroup cols="4" align="left"> <thead> <row> <entry>name</entry> <entry>type</entry> <entry>description</entry> <entry>default value</entry> </row> </thead> <tbody> <row> <entry>method</entry> <entry>STRING</entry> <entry> This attribute specifies HTTP method used in request. Valid values include: GET, POST, HEAD. </entry> <entry>GET</entry> </row> <row> <entry>payload</entry> <entry>STRING</entry> <entry> This attribute specifies POST request body. Contents of this attribute are sent raw as POST request body, so they need to be properly encoded. </entry> <entry>(empty)</entry> </row> <row> <entry>payloadparam</entry> <entry>STRING</entry> <entry> FIXME: need content here. </entry> <entry>(empty)</entry> </row> <row> <entry>payloadparamcount</entry> <entry>INTEGER</entry> <entry> FIXME: need content here. </entry> <entry>0</entry> </row> <row> <entry>payloadtemplate</entry> <entry>STRING</entry> <entry> This attribute holds POST request body, that will be searched for variables. Every variable found would be expanded to it's value. </entry> <entry>(empty)</entry> </row> <row> <entry>responsename</entry> <entry>STRING</entry> <entry> This attribute sets the name of variable, that will be created upon successful match of responsetemplate. </entry> <entry>(empty)</entry> </row> <row> <entry>responsetemplate</entry> <entry>STRING</entry> <entry> This attribute holds regular expression that will be matched against response. If successful, resulting string will be placed in newly created variable, whose name is determined by responsename attribute. </entry> <entry>(empty)</entry> </row> <row> <entry>requesttemplate</entry> <entry>STRING</entry> <entry> This attribute holds the URL address, that will be searched for variables. Every variable found will be expanded to it's value. Presence of this attribute makes url an empty element. </entry> <entry>(empty)</entry> </row> <row> <entry>requestparamcount</entry> <entry>INTEGER</entry> <entry> FIXME: need content here. </entry> <entry>0</entry> </row> <row> <entry>predelay</entry> <entry>INTEGER</entry> <entry> FIXME: need content here. </entry> <entry>0</entry> </row> <row> <entry>predelayprecision</entry> <entry>INTEGER</entry> <entry> FIXME: need content here. </entry> <entry>0</entry> </row> <row> <entry>postdelay</entry> <entry>INTEGER</entry> <entry> FIXME: need content here. </entry> <entry>0</entry> </row> <row> <entry>postdelayprecision</entry> <entry>INTEGER</entry> <entry> FIXME: need content here. </entry> <entry>0</entry> </row> <row> <entry>user</entry> <entry>STRING</entry> <entry> This attribute holds username for auth (401 header). </entry> <entry>(empty)</entry> </row> <row> <entry>password</entry> <entry>STRING</entry> <entry> This attribute holds password for auth (401 header). </entry> <entry>(empty)</entry> </row> </tbody> </tgroup> </informaltable> </refsection> <refsection> <title>character data</title> <para>none | specifies URL address for retrieval.</para> </refsection> <refsection> <title>description</title> <para> This element is the basic data unit of flood. It contains detailed description of url address scheduled for retrieval. You can specify how to perform request (method, optional payload) and how to postprocess response. </para> </refsection> <refsection> <title>examples</title> <screen> <urllist> <name>check release</name> <url responsename="filename" responsetemplate="href=(.*)">http://www.example.com/downloads/</url> <url requesttemplate="http://www.example.com/files/${filename}" requestparamcount="1"/> <!-- ... --> </urllist> </screen> </refsection> </refentry> <refentry id="sequence"> <refmeta> <refentrytitle>sequence</refentrytitle> </refmeta> <refnamediv> <refname>sequence</refname> <refpurpose>generates sequence of urls</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><sequence sequencename="STRING" sequencelist="INTEGER"> ... </sequence></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="urllist"><urllist></link></synopsis> </refsection> <refsection> <title>children elements</title> <synopsis><link linkend="url"><url></link>* <link linkend="sequence"><sequence></link>*</synopsis> </refsection> <refsection> <title>attributes</title> <informaltable frame="all"> <tgroup cols="4" align="left"> <thead> <row> <entry>name</entry> <entry>type</entry> <entry>description</entry> <entry>default value</entry> </row> </thead> <tbody> <row> <entry>sequencename</entry> <entry>STRING</entry> <entry> This attribute specifies the name of current sequence. </entry> <entry>(empty)</entry> </row> <row> <entry>sequencelist</entry> <entry>STRING</entry> <entry> This attribute holds coma separated list of sequence iteration values. </entry> <entry>(empty)</entry> </row> </tbody> </tgroup> </informaltable> </refsection> <refsection> <title>character data</title> <para>ignored.</para> </refsection> <refsection> <title>description</title> <para> This element allows a creation of simple sequence of URLs. This allows certain URL patterns to be simplified. </para> </refsection> <refsection> <title>examples</title> <screen> <urllist> <sequence sequencename="myseq" sequencelist="bob, jane, joe"> <url requesttemplate="http://www.you.com/~${myseq}/" /> <url requesttemplate="http://www.you.com/~${myseq}/index.html" /> </sequence> </urllist> </screen> </refsection> </refentry> <refentry id="profile"> <refmeta> <refentrytitle>profile</refentrytitle> </refmeta> <refnamediv> <refname>profile</refname> <refpurpose>describes farmer profile</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><profile> ... </profile></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="flood"><flood></link></synopsis> </refsection> <refsection> <title>children elements</title> <synopsis><link linkend="name"><name></link> [ <link linkend="description"><description></link> ] <link linkend="useurllist"><useurllist></link> <link linkend="profiletype"><profiletype></link> [ <link linkend="socket"><socket></link> ] <link linkend="verify_resp"><verify_resp></link> [ <link linkend="report"><report></link> ]</synopsis> <!-- FIXME: describe all events in detail? --> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>ignored.</para> </refsection> <refsection> <title>description</title> <para> This element describes profile of a farmer. Profile describes farmer behaviour in detail. What farmer does and how he does it. </para> </refsection> <refsection> <title>examples</title> <screen> <profile> <name>my profile</name> <profiletype>round_robin</profiletype> <useurllist>my urls</useurllist> <verify_resp>verify_200</verify_resp> <report>simple</report> </profile> </screen> </refsection> </refentry> <refentry id="useurllist"> <refmeta> <refentrytitle>useurllist</refentrytitle> </refmeta> <refnamediv> <refname>useurllist</refname> <refpurpose>urllist to use in profile</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><useurllist>STRING</useurllist></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="profile"><profile></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>name of urllist to use.</para> </refsection> <refsection> <title>description</title> <para> This element references an exisiting urllist, which will be used in current profile. If there's no urllist by that name, flood will report error and exit. </para> </refsection> <refsection> <title>examples</title> <screen> <urllist> <name>my urls</name> <-- ... --> </urllist> <-- ... --> <profile> <-- ... --> <useurllist>my urls</useurllist> <-- ... --> </profile> </screen> </refsection> </refentry> <refentry id="profiletype"> <refmeta> <refentrytitle>profiletype</refentrytitle> </refmeta> <refnamediv> <refname>profiletype</refname> <refpurpose>specifies type of profile</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><profiletype>STRING</profiletype></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="profile"><profile></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>name of profile type.</para> </refsection> <refsection> <title>description</title> <para> This element specifies type of profile. Actually there is only one valid profile type -- <synopsis>round_robin</synopsis>. </para> </refsection> <refsection> <title>examples</title> <screen> <profile> <-- ... --> <profiletype>round_robin</profiletype> <-- ... --> </profile> </screen> </refsection> </refentry> <refentry id="socket"> <refmeta> <refentrytitle>socket</refentrytitle> </refmeta> <refnamediv> <refname>socket</refname> <refpurpose>specifies profile socket type</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><socket>STRING</socket></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="profile"><profile></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>profile socket type.</para> </refsection> <refsection> <title>description</title> <para> <!-- FIXME: we need verbatim tag instead of envar --> This element specifies socket type to be used in conjunction with current profile. Valid examples are <envar>generic</envar>, <envar>keepalive</envar> and <envar>ssl</envar>. In practice <envar>generic</envar> socket allows for one request per connection (connection is terminated right after receiving response), while <envar>keepalive</envar> allows for more than one request to be transmitted over active connection. This difference can have significant impact on test results. </para> </refsection> <refsection> <title>examples</title> <screen> <profile> <-- ... --> <socket>generic</socket> <-- ... --> </profile> </screen> </refsection> </refentry> <refentry id="verify_resp"> <refmeta> <refentrytitle>verify_resp</refentrytitle> </refmeta> <refnamediv> <refname>verify_resp</refname> <refpurpose>specifies response verification type</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><verify_resp>STRING</verify_resp></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="profile"><profile></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>response verification type.</para> </refsection> <refsection> <title>description</title> <para> This element specifies type of response verification. Valid examples are <envar>verify_200</envar> and <envar>verify_http_code</envar>. Both types assume 3xx and 2xx responses are valid, and other are not. In practice, <envar>verify_200</envar> is very fast, while <envar>verify_http_code</envar> is safe with carefull response parsing. Please use <envar>verify_http_code</envar> if you experience problems. </para> <note> <para> Flood recognizes 3xx type responses (so called redirects) as valid responses, but do not follows them. Following 3xx type responses will probably become optional in near future. </para> </note> </refsection> <refsection> <title>examples</title> <screen> <profile> <-- ... --> <verify_resp>verify_200</verify_resp> <-- ... --> </profile> </screen> </refsection> </refentry> <refentry id="report"> <refmeta> <refentrytitle>report</refentrytitle> </refmeta> <refnamediv> <refname>report</refname> <refpurpose>specifies reporting type</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><report>STRING</report></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="profile"><profile></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>report type.</para> </refsection> <refsection> <title>description</title> <para> This element specifies report type to be used in conjunction with current profile. Valid examples are <envar>simple</envar>, <envar>easy</envar> and <envar>relative_times</envar>. </para> </refsection> <refsection> <title>examples</title> <screen> <profile> <-- ... --> <socket>generic</socket> <-- ... --> </profile> </screen> </refsection> </refentry> <refentry id="farmer"> <refmeta> <refentrytitle>farmer</refentrytitle> </refmeta> <refnamediv> <refname>farmer</refname> <refpurpose>defines a virtual working human</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><farmer> ... </farmer></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="flood"><flood></link></synopsis> </refsection> <refsection> <title>children elements</title> <synopsis><link linkend="name"><name></link> [ <link linkend="description"><description></link> ] [ { <link linkend="count"><count></link> | <link linkend="time"><time></link> } ] <link linkend="useprofile"><useprofile></link></synopsis> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>ignored.</para> </refsection> <refsection> <title>description</title> <para> This element defines basic flood work unit. A farmer can be (depending on compile-time configuration) a separate process, or a threead withing main flood process. </para> </refsection> <refsection> <title>examples</title> <screen> <farmer> <name>john</name> <useprofile>my profile</useprofile> </farmer> </screen> </refsection> </refentry> <refentry id="useprofile"> <refmeta> <refentrytitle>useprofile</refentrytitle> </refmeta> <refnamediv> <refname>useprofile</refname> <refpurpose>profile to be used by farmer</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><useprofile>STRING</useprofile></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="farmer"><farmer></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>name of profile to be used by farmer.</para> </refsection> <refsection> <title>description</title> <para> This element references an exisiting profile, which will be used by current farmer. If there's no profile by that name, flood will report error and exit. </para> </refsection> <refsection> <title>examples</title> <screen> <profile> <name>my profile</name> <!-- ... --> </profile> <!-- ... --> <farmer> <name>john</name> <useprofile>my profile</useprofile> </farmer> </screen> </refsection> </refentry> <refentry id="count"> <refmeta> <refentrytitle>count</refentrytitle> </refmeta> <refnamediv> <refname>count</refname> <refpurpose>amount of farmer work loops</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><count>INTEGER<count></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="farmer"><farmer></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>amount of full work loops.</para> </refsection> <refsection> <title>description</title> <para> This element specifies amount of loops that schould be performed by farmer. The amount of work in loop depends on profile, but it usually means hitting all url's from urllist. </para> </refsection> <refsection> <title>examples</title> <screen> <farmer> <name>john</name> <count>5</count> <useprofile>my profile</useprofile> </farmer> </screen> </refsection> </refentry> <refentry id="time"> <refmeta> <refentrytitle>time</refentrytitle> </refmeta> <refnamediv> <refname>time</refname> <refpurpose>duration of farmer work</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><time>INTEGER<time></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="farmer"><farmer></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>duration of farmer work in seconds.</para> </refsection> <refsection> <title>description</title> <para> This element specifies duration of farmer work in seconds. If specified time is greater than time needed to perform full work loop, then farmer starts another work loop. </para> </refsection> <refsection> <title>examples</title> <screen> <farmer> <name>john</name> <time>20</time> <useprofile>my profile</useprofile> </farmer> </screen> </refsection> </refentry> <refentry id="farm"> <refmeta> <refentrytitle>farm</refentrytitle> </refmeta> <refnamediv> <refname>farm</refname> <refpurpose>a group of farmers</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><farm> ... </farm></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="flood"><flood></link></synopsis> </refsection> <refsection> <title>children elements</title> <synopsis><link linkend="name"><name></link> [ <link linkend="description"><description></link> ] <link linkend="usefarmer"><usefarmer></link></synopsis> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>ignored.</para> </refsection> <refsection> <title>description</title> <para> This element defines a work unit, that is a container for flood basic work unit -- farmer. With farm you can easily clone elements. </para> <warning> <para> Because there are issues involved in determining how flood starts farm processing (first one? all of them?) currently flood *requires* only one farm with name "Bingo" (case sensitive). </para> </warning> </refsection> <refsection> <title>examples</title> <screen> <farm> <name>Bingo</name> <usefarmer>john</usefarmer> </farm> </screen> </refsection> </refentry> <refentry id="usefarmer"> <refmeta> <refentrytitle>usefarmer</refentrytitle> </refmeta> <refnamediv> <refname>usefarmer</refname> <refpurpose>specifies farmer to use in farm</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><usefarmer [ count="INTEGER" ] [ startcount="INTEGER" ] [ startdelay="INTEGER" ]>STRING</usefarmer></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="farm"><farm></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <informaltable frame="all"> <tgroup cols="4" align="left"> <thead> <row> <entry>name</entry> <entry>type</entry> <entry>description</entry> <entry>default value</entry> </row> </thead> <tbody> <row> <entry>count</entry> <entry>INTEGER</entry> <entry> This attribute specifies amount of farmers to "clone". </entry> <entry>0</entry> </row> <row> <entry>startcount</entry> <entry>INTEGER</entry> <entry> This attribute specifies amount of farmers to start each time. </entry> <entry>0</entry> </row> <row> <entry>startdelay</entry> <entry>INTEGER</entry> <entry> This attribute specifies amount of time (in seconds) between each farmer start. </entry> <entry>0</entry> </row> </tbody> </tgroup> </informaltable> </refsection> <refsection> <title>character data</title> <para>name of farmer to use</para> </refsection> <refsection> <title>description</title> <para> This element asociates farmer with farm. In addition, it is possible to "clone" farmer -- that is -- to have several separate parallel farmers with identical behaviour (profile, urls). </para> </refsection> <refsection> <title>examples</title> <screen> <farm> <name>Bingo</name> <usefarmer count="2">john</usefarmer> </farm> </screen> </refsection> </refentry> <refentry id="seed"> <refmeta> <refentrytitle>seed</refentrytitle> </refmeta> <refnamediv> <refname>seed</refname> <refpurpose>specifies fixed seed for PRNG</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><seed>INTEGER</seed></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="flood"><flood></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> </refsection> <refsection> <title>attributes</title> <para>none.</para> </refsection> <refsection> <title>character data</title> <para>fixed seed for PRNG.</para> </refsection> <refsection> <title>description</title> <para> During tests flood sometimes uses system PRNG (Pseudo Random Number Generator). For example, this happens when you use <envar>${=name}</envar> construct. Since numbers returned by PRNG are different for every test, you can have situation in which the same set of URLS has very different results. Consider retrieval of article from database with such url: </para> <screen> <url requesttemplate="http://www.example.com/show_art.php?id=${=aid}"/> </screen> <para> When you run the test for the first time, <envar>aid</envar> evaluates to 6, and results in a 20 KB article. However at the second run <envar>aid</envar> evaluates to 216 which can trigger a more complex query, or return a larger article (say 108 KB). You used the same config, but results are different. If you use <seed> element with a fixed value (like 23, 48 or 84) you can expect PRNG to generate the same number with every run. </para> </refsection> <refsection> <title>examples</title> <screen> <seed>23</seed> </screen> </refsection> </refentry> <!-- refentry TEMPLATE, 77 lines <refentry id="NAME"> <refmeta> <refentrytitle>NAME</refentrytitle> </refmeta> <refnamediv> <refname>NAME</refname> <refpurpose>PURPOSE</refpurpose> </refnamediv> <refsynopsisdiv> <title>synopsis</title> <synopsis><NAME ATTR1="STRING" ATTR2="INTEGER"></synopsis> </refsynopsisdiv> <refsection> <title>parent elements</title> <synopsis><link linkend="PARENT"><PARENT></link></synopsis> </refsection> <refsection> <title>children elements</title> <para>none.</para> OR <synopsis><link linkend="CHILD"><CHILD></link></synopsis> </refsection> <refsection> <title>attributes</title> <para>none.</para> OR <informaltable frame="all"> <tgroup cols="4" align="left"> <thead> <row> <entry>name</entry> <entry>type</entry> <entry>description</entry> <entry>default value</entry> </row> </thead> <tbody> <row> <entry>ATTR</entry> <entry>TYPE</entry> <entry>DESCRIPTION</entry> <entry>VALUE</entry> </row> </tbody> </tgroup> </informaltable> </refsection> <refsection> <title>character data</title> <para>ignored.</para> OR <para>DESCRIPTION</para> </refsection> <refsection> <title>description</title> <para>DESCRIPTION</para> </refsection> <refsection> <title>examples</title> <screen> <NAME>REAL_VALUE</NAME> </screen> </refsection> </refentry> --> </chapter> <chapter> <title>Analyzing Flood output</title> <para>This section needs to be written. Volunteers? -- jacekp</para> </chapter> </book>